#include "StdAfx.h"
#include <fstream>
#include <iostream>
#include "XMLNode.h"
using namespace rapidxml;



void XMLDoc::Save( const TCHAR* fileName )
{
	std::basic_ofstream<TCHAR>  xml_file(fileName);
	xml_file.imbue(std::locale("CHS"));
	xml_file<<*mpDoc;
}

void XMLDoc::Read( const TCHAR* fileName )
{

	std::basic_ifstream<TCHAR> xml_file(fileName, std::ios::binary);
	xml_file.imbue(std::locale("CHS"));
	if(xml_file){
		cpputil::autoPtrReset(mpReadFile , new _xmlFileContent(xml_file));
		mpDoc->parse<0>(mpReadFile->data());		
	}


}	

XMLNode XMLDoc::newElement( const TCHAR* sName )
{
	return  XMLNode(mpDoc->allocate_node(rapidxml::node_element,sName));
}

void XMLDoc::addElement( const XMLNode& elm )
{
	mpDoc->append_node(elm.mpNode);
}

void XMLDoc::Print()
{
	std::wstring text;  
	rapidxml::print(std::back_inserter(text), *mpDoc, 0);  
	std::wcout<<text;

}

XMLDoc::~XMLDoc()
{
	cpputil::autoPtrReset(mpDoc);
	cpputil::autoPtrReset(mpReadFile);
}

XMLDoc::XMLDoc()
{
	mpDoc = new _xmlDoc();
	mpReadFile = 0;
}

TCHAR* XMLNode::getNodeType()const
{
	if(mpNode)
		return mpNode->name();
	return sBlank;
}



void XMLNode::addChild( const XMLNode& elm )
{
	mpNode->append_node(elm.mpNode);
}	

XMLNode XMLNode::getParent()const
{
	return XMLNode(mpNode->parent());
}

XMLNode XMLNode::firstChildNode(const TCHAR* name)const
{
	return XMLNode(mpNode->first_node(name));
}

XMLNode XMLNode::nextSibNode(const TCHAR* name)const
{
	return XMLNode(mpNode->next_sibling(name));
}

XMLNode XMLNode::firstChildElement( const TCHAR* name/*=0*/ )const
{
	XMLNode child =  firstChildNode(name);
	while(child ){
		if(child.isElement())
			return child;
	}
	return XMLNode(NULL);
}

bool XMLNode::isElement() const
{
	return mpNode->type()==rapidxml::node_element;
}

bool XMLNode::isComment() const
{
	return mpNode->type()==rapidxml::node_comment;
}

XMLNode XMLNode::nextSibElement( const TCHAR* name/*=0*/ )const
{
	XMLNode next = nextSibNode(name);
	while (next){
		if(next.isElement()){
			return next;
		}
	}
	return XMLNode(NULL);
}

XMLNode& XMLNode::setAttribute( const TCHAR*sAttri, const TCHAR* val )
{
	_xmlDoc* pdoc = mpNode->document();
	TCHAR* sval = pdoc->allocate_string(val);
	if(_xmlAttribute* pAttri = mpNode->first_attribute(sAttri) ){
		pAttri->value(sval);
	}
	else{
		mpNode->append_attribute( pdoc->allocate_attribute(sAttri,sval) );
	}
	return *this;
}

const TCHAR* XMLNode::getAttribute( const TCHAR* sAttri )const
{
	if(_xmlAttribute* pattri = mpNode->first_attribute(sAttri))
	{
		return pattri->value();

	}
	return sBlank;
}

XMLNode XMLNode::createChildElement( const TCHAR* name )
{
	_xmlNode* pchild = mpNode->document()->allocate_node(rapidxml::node_element,name);
	mpNode->append_node(pchild);
	return pchild;
}

bool XMLNode::hasAttribute( const TCHAR*sAttri ) const
{
	return mpNode->first_attribute(sAttri)!=NULL;
}

XMLNode& XMLNode::removeAttribute( const TCHAR*sAttri )
{
	while(_xmlAttribute* pattri = mpNode->first_attribute(sAttri)){
		mpNode->remove_attribute(pattri);
	}
	return *this;
}

bool XMLNode::removeChildNode( const XMLNode& node )
{
	if(node.getParent() == *this)
	{
		mpNode->remove_node(node.mpNode);
		return true;
	}
	return false;
}

const TCHAR* XMLNode::getText() const
{
	return mpNode->value();
}

void XMLNode::setText( const TCHAR* s )
{
	_xmlDoc* pdoc = mpNode->document();
	TCHAR* sval = pdoc->allocate_string(s);
	mpNode->value(sval);
}

int XMLNode::GetID() const
{
	int nID;
	if(cpputil::strConvert(getAttribute(aID),nID) )
	{
		return nID;
	}
	return -1;
}

void XMLNode::SetID( int id )
{
	
}

TCHAR XMLNode::sBlank[] = _T("");

TCHAR XMLNode::aID[] = _T("id");
TCHAR XMLNode::aName[]  = _T("name");





